import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { contextBridge, ipcRenderer } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
import * as ip from 'ip'
import { CHROME_BOOKMARKS_PATH } from './constants'
import type { IgnoreMouseEventsOptions } from 'electron';

// Custom APIs for renderer
const api = {
  shortcut: (type: WindowType, shortcutKey: string) => {
    return ipcRenderer.invoke('shortcut', type, shortcutKey)
  },
  setIgnoreMouseEvents: (
    ignore: boolean,
    options?: IgnoreMouseEventsOptions,
  ) => {
    ipcRenderer.send('setIgnoreMouseEvents', ignore, options)
  },
  openWindow: (type: WindowType) => {
    ipcRenderer.send('openWindow', type)
  },
  closeWindow: (type: WindowType) => {
    ipcRenderer.send('closeWindow', type)
  },
  reloadWindow: (type: WindowType) => {
    ipcRenderer.send('reloadWindow', type)
  },
  sql: (sql: string, type: QueryAction, data = {}) => {
    return ipcRenderer.invoke('sql', sql, type, data)
  },
  // 开机启动
  openAtLogin: (bool: boolean) => {
    ipcRenderer.send('openAtLogin', bool)
  },
  getOpenAtLogin: () => {
    return ipcRenderer.invoke('getOpenAtLogin')
  },
  onSearchShow: (callback: () => void) => {
    ipcRenderer.on('show-search-window', callback)
  },
  setWin: (type: SetWinType) => ipcRenderer.send(type),
  isMaximized: () => ipcRenderer.invoke('isMaximized'),
  dragWindow: (type: WindowType, x: number, y: number) => {
    ipcRenderer.send('dragWindow', type, x, y)
  },
  getIpadress: () => {
    return ip.address()
  },
  openExternal: (url: string) => {
    ipcRenderer.send('openExternal', url)
  },
  async getChromeBookmarks () {
    const homePath = await ipcRenderer.invoke('getHomePath')
    return JSON.parse(await readFile(
      join(join(homePath, CHROME_BOOKMARKS_PATH)),
      'utf-8',
    ))
  },
  translate (
    text: string,
    source?: string,
    target?: string,
  ) {
    return ipcRenderer.invoke('translate', text, source, target)
  },
  toBuffer (
    arrayBuffer: WithImplicitCoercion<ArrayBuffer | SharedArrayBuffer>,
    byteOffset?: number,
    length?: number,
  ) {
    return Buffer.from(arrayBuffer, byteOffset, length)
  },
  saveImage (buffer: Buffer, fileName: string) {
    return ipcRenderer.invoke('saveImage', buffer, fileName)
  },
  loadImage (filePath: string) {
    return ipcRenderer.invoke('loadImage', filePath)
  },
  getInstalledApps: (forceRefresh = false) => {
    return ipcRenderer.invoke('getInstalledApps', forceRefresh)
  },
  searchInstalledApps: (keyword: string) => {
    return ipcRenderer.invoke('searchInstalledApps', keyword)
  },
}

// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {
  try {
    contextBridge.exposeInMainWorld('electron', electronAPI)
    contextBridge.exposeInMainWorld('api', api)
  } catch (error) {
    console.error(error)
  }
} else {
  // @ts-ignore (define in dts)
  window.electron = electronAPI
  // @ts-ignore (define in dts)
  window.api = api
}
